#!/usr/bin/env python
# -*- coding: utf-8 -*-
#===============================================================================
#
#          FILE:  lighttpd-vhost.py
# 
#         USAGE:  ./lighttpd-vhost.py www.pnote.cn
# 
#   DESCRIPTION:  自动整理lighttpd下的目录结构，并且增加虚拟主机配置
# 
#       OPTIONS:  ---
#  REQUIREMENTS:  ---
#          BUGS:  ---
#         NOTES:  ---
#        AUTHOR:  Zengpu Zhang (zengpuzhang@gmail.com), 
#       COMPANY:  
#       VERSION:  0.1
#       CREATED:  2009年04月15日 17时10分24秒 EDT
#      REVISION:  $Id: lighttpd-vhost.py 15 2009-04-21 04:40:24Z zengpuzhang $
#===============================================================================

#-------------------------------------------------------------------------------
# 基本需求
#
# * 整理归顺lighttpd配置目录，参考apache的配置，使各个物件均有自己的位置
# * 增加接口，输入相应的参数，以便自动生成配置文件，当输入不全的时候，输出帮助信息
# * 当网站已经配置是，自动备份原来的配置文件
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
# 加载需要的类库
#-------------------------------------------------------------------------------
import os,sys,errno,re,time,shutil
import getopt


#-------------------------------------------------------------------------------
# 基本配置
#-------------------------------------------------------------------------------
__version__ = "$Id: lighttpd-vhost.py 15 2009-04-21 04:40:24Z zengpuzhang $"
VERSION = '0.1'


#===  FUNCTION  ================================================================
#          NAME:  inred
#   DESCRIPTION:  改变屏幕输出字符为红色
#    PARAMETERS:  string
#       RETURNS:  红色的string
#===============================================================================
def inred( s ):
	"""改变屏幕输出字符为红色"""
	return "%s[31;2m%s%s[0m"%(chr(27), s, chr(27))

#===  FUNCTION  ================================================================
#          NAME:  ingreen
#   DESCRIPTION:  改变屏幕输出字符为绿色
#    PARAMETERS:  string
#       RETURNS:  红色的string
#===============================================================================
def ingreed( s ):
	"""改变屏幕输出字符为绿色"""
	return "%s[32;2m%s%s[0m"%(chr(27), s, chr(27))

#===  FUNCTION  ================================================================
#          NAME:  fixdir
#   DESCRIPTION:  修正目录
#    PARAMETERS:  string
#       RETURNS:  
#===============================================================================
def fixdir( s ):
	"""修正目录"""
	isdir = os.path.exists(s)
	if isdir == False:
		os.makedirs(s)
	print "["+ingreed('ok')+"] stable:" + s	

#===  FUNCTION  ================================================================
#          NAME:  writerIncludeSiteEnabledPl
#   DESCRIPTION:  写入网站配置信息
#    PARAMETERS:  
#       RETURNS:  
#===============================================================================
def writerIncludeSiteEnabledPl():
	"""写入网站配置信息"""
	#print 'writerIncludeSiteEnabledPl'
	sitesEnabledFile = '/usr/share/lighttpd/include-sites-enabled.pl'
	isfile = os.path.exists( sitesEnabledFile )
	if isfile == True :
		print "["+ingreed('ok')+"] stable:" + sitesEnabledFile
	else:		
		fp = open(sitesEnabledFile, 'w')	
		fp.writelines("#!/usr/bin/perl -wl\n")
		fp.writelines("\n")
		fp.writelines("use strict;\nuse File::Glob ':glob';\n")
		fp.writelines("\n")
		fp.writelines("my $confdir = \"/etc/lighttpd/\";\n")
		fp.writelines("my $enabled = \"sites-enabled/*\";\n")
		fp.writelines("\n")
		fp.writelines("chdir($confdir);\n")
		fp.writelines("my @files = bsd_glob($enabled);\n")
		fp.writelines("\n")	
		fp.writelines("for my $file (@files)\n")
		fp.writelines("{\n")
		fp.writelines("	print \"include \\\"$file\\\"\";\n")
		fp.writelines("}")
		fp.close()
		os.chmod(sitesEnabledFile, 0755)
		print "["+ingreed('ok')+"] File Create:" + sitesEnabledFile

#===  FUNCTION  ================================================================
#          NAME:  writeLighttpdConf
#   DESCRIPTION:  修改lighttpd.conf
#    PARAMETERS:  
#       RETURNS:  
#===============================================================================	
def writeLighttpdConf():
	"""修改lighttpd.conf"""
	lighttpdConf = '/etc/lighttpd/lighttpd.conf'	
	
	fp = open(lighttpdConf, "r")
	allConfData = fp.read()
	fp.close()
	now = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) 
	
	m = re.search('include_shell.*/usr/share/lighttpd/include-sites-enabled.pl', allConfData)	
	if m == None :
		allConfData = allConfData+("## load enabled sites files,\n")
		allConfData = allConfData+("## create at "+now+"\n")
		allConfData = allConfData+("include_shell \"/usr/share/lighttpd/include-sites-enabled.pl\"\n")
	
		fp = open(lighttpdConf, "w")
		fp.write(allConfData)
		fp.close()
		print "["+ingreed('ok')+"] Modify File:" + lighttpdConf
	else:
		print "["+ingreed('ok')+"] stable:" + lighttpdConf

#===  FUNCTION  ================================================================
#          NAME:  checkRootUser
#   DESCRIPTION:  检测运行的用户权限
#    PARAMETERS:  
#       RETURNS:  
#===============================================================================
def checkRootUser():
	"""判断运行程序的用户及权限"""
	uid = os.getuid()
	if uid != 0:
		print "["+inred("*")+"] lighttpd-vhost.py must be running under the root permissions"
		sys.exit(1)

#-------------------------------------------------------------------------------
# 检测是否安装lighttpd及其配置文件结构，并改正之。
#-------------------------------------------------------------------------------
def checkLighttpdIsInstalled():
	result = os.popen('dpkg -l | grep lighttpd | wc -l')
	result = result.read()
	if result[0] == '0' :
		print inred('[*]')+" to install lighttpd use the commod:"
		print 'sudo apt-get install lighttpd'
		sys.exit(1)
#-------------------------------------------------------------------------------
# 配置单个虚拟主机
#-------------------------------------------------------------------------------
def writeVhostSite( domain , documentRoot):
	"""配置单个虚拟主机"""
	
	siteAvailableConfFile = "/etc/lighttpd/sites-available/"+domain
	siteEnabledConfFile = "/etc/lighttpd/sites-enabled/"+domain
	serverErrorLog = "/var/log/lighttpd/"+domain+".error.log"
	serverAccessLog = "/var/log/lighttpd/"+domain+".access.log"
	now = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) 
	isFile = os.path.exists(siteAvailableConfFile)		
	
	if isFile == True:
		"""备份原来文件"""
		newFile = "/etc/lighttpd/sites-available/"+domain+"."+now
		shutil.copyfile(siteAvailableConfFile, newFile)
		print "["+ingreed('ok')+"] Backup File Named:" + newFile
		"""新的创建"""		
		fp = open(siteAvailableConfFile, 'w')	
		fp.writelines("# create at "+now+"\n")
		fp.writelines("###"+domain+"\n")
		fp.writelines("$HTTP[\"host\"] == \""+domain+"\" {  \n")	
		fp.writelines("\n")
		fp.writelines("	server.document-root = \""+documentRoot+"\"\n")
		fp.writelines("	server.error-handler-404 = \"/index.html\"\n")
		fp.writelines("	#url.redirect = (  \n")	
		fp.writelines("		#\"^/index.php*\" => \"http://"+domain+"/\",\n")	
		fp.writelines("	#)\n")	
		fp.writelines("	server.errorlog = \""+serverErrorLog+"\"\n")
		fp.writelines("	accesslog.filename =\""+serverAccessLog+"\"\n")
		fp.writelines("	server.indexfiles = ( \"index.html\", \"index.php\")\n")
		fp.writelines("	#其他的配置暂略，更多定制的配置需到\n")
		fp.writelines("	#http://code.google.com/p/lighttpd-vhost/\n")	
		fp.writelines("	#获取\n")	
		fp.writelines("	}\n")
		fp.close()	
		forceSymlink(siteAvailableConfFile, siteEnabledConfFile)
		
	else:
		"""新的创建"""		
		fp = open(siteAvailableConfFile, 'w')	
		fp.writelines("# create at "+now+"\n")
		fp.writelines("###"+domain+"\n")
		fp.writelines("$HTTP[\"host\"] == \""+domain+"\" {  \n")	
		fp.writelines("\n")
		fp.writelines("	server.document-root = \""+documentRoot+"\"\n")
		fp.writelines("	server.error-handler-404 = \"/index.html\"\n")
		fp.writelines("	#url.redirect = (  \n")	
		fp.writelines("		#\"^/index.php*\" => \"http://"+domain+"/\",\n")	
		fp.writelines("	#)\n")	
		fp.writelines("	server.errorlog = \""+serverErrorLog+"\"\n")
		fp.writelines("	accesslog.filename =\""+serverAccessLog+"\"\n")
		fp.writelines("	server.indexfiles = ( \"index.html\", \"index.php\")\n")
		fp.writelines("	#其他的配置暂略，更多定制的配置需到\n")
		fp.writelines("	#http://code.google.com/p/lighttpd-vhost/\n")	
		fp.writelines("	#获取\n")	
		fp.writelines("	}\n")
		fp.close()	
		forceSymlink(siteAvailableConfFile, siteEnabledConfFile)	
	print "["+ingreed('ok')+"] New File Create:" + siteAvailableConfFile
	print "["+ingreed('ok')+"] Link to:" + siteEnabledConfFile
	
#-------------------------------------------------------------------------------
# 强制创建链接
#-------------------------------------------------------------------------------
def forceSymlink(file1, file2):
	try:
		os.symlink(file1, file2)
	except OSError, e:
		if e.errno == errno.EEXIST:
			os.remove(file2)
			os.symlink(file1, file2)
			

#-------------------------------------------------------------------------------
# 输入参数处理
#-------------------------------------------------------------------------------
class Options:
	
	def __init__(self, args):
		self.stdout = False
		self.domain = []
		### Get options from the commandline
		try:
			opts, args = getopt.getopt (args, 'h:v',['help','version'] )
			
		except getopt.error, exc:
			self.help()
			sys.exit(255)           
	       
	       
		for opt, arg in opts:
			if opt in ['-h', '--help']:
				self.usage()
				print
				self.help()
				sys.exit(1)
			elif opt in ['-v', '--version']:
				self.version()
				sys.exit(255)
			else :
				self.help()
				sys.exit(1)
		self.domain = args
        
	def version(self):
		print 'lighttpd-vhost %s Zengpu Zhang <zengpuzhang@gmail.com>' % VERSION        
		print 'http://code.google.com/p/lighttpd-vhost/'
		print
		print 'build revision $Id: lighttpd-vhost.py 15 2009-04-21 04:40:24Z zengpuzhang $'

	def usage(self):
		print >>sys.stderr, 'usage: ./lighttpd-vhost.py [options] domain [document-root]'
	
	def help(self):
		print >>sys.stderr, '''Automatically organize lighttpd, and increase the Virtual Host Configuration

lighttpd-vhost.py options:   
  -v, --version            show version
  -h, --help               show help
  
  
lighttpd-vhost.py example:   
  ./lighttpd-vhost.py pnote.cn
  ./lighttpd-vhost.py www.pnote.cn "/home/www/www.pnote.cn"  

'''

def main():
	
	try:
		#开始处理domain
		domain = op.domain[0]
		isDomain = str.rfind(domain,'.')
		if isDomain < 1 :
			print "["+inred('Error!')+"] Please enter a legitimate domain name\n"            
			sys.exit(0)
		else:
			pass
		
				
		fixdir('/etc/lighttpd/sites-enabled')
		fixdir('/etc/lighttpd/sites-available')
		#-------------------------------------------------------------------------------
		# 写入文件
		#-------------------------------------------------------------------------------
		writerIncludeSiteEnabledPl()
		writeLighttpdConf()
		#处理地址
		if len(op.domain) > 1 :
			documentRoot = op.domain[1]            
		else:
			documentRoot = "/var/www/"+op.domain[0]
			
		#网站目录        
		fixdir(documentRoot)        
		writeVhostSite( domain ,documentRoot ) 
		print "\n"
		print "["+ingreed('Done')+"] New Site "+domain
		print "\n"
		
		print "[run] "+inred("/etc/init.d/lighttpd restart")+" [to restart lighttpd server]"
	
	except:
		op.help()
		sys.exit(255)

if __name__ == '__main__':    

	#-------------------------------------------------------------------------------
	# 检测系统
	#-------------------------------------------------------------------------------
	checkRootUser()
	checkLighttpdIsInstalled()
	
	op = Options(sys.argv[1:])  
	
	main()
